package com.zh.business.controller.mp;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.github.AopLog;
import com.zh.business.service.mp.WechatService;
import com.zh.business.service.mp.MiniUserInfoService;
import com.zh.business.util.CommonUtils;
import com.zh.business.vo.web.MiniUserVo;
import com.zh.zhbootcommon.common.BasicConstants;
import com.zh.zhbootcommon.common.RedisKey;
import com.zh.zhbootcommon.common.result.impl.ResultCode;
import com.zh.zhbootcommon.domain.DResult;
import com.zh.zhbootcommon.entity.mp.MiniUserInfo;
import com.zh.zhbootcommon.utils.common.RedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.Objects;

/**
 * 描述: 小程序用户相关
 *
 * @author: yanglin
 * @Date: 2021-08-16-13:41
 * @Version: 1.0
 */
@Slf4j
@RestController
@RequestMapping("/mp/l/v1")
@Api(value = "小程序用户相关")
@AopLog(type = "小程序用户相关",stackTraceOnErr = true)
public class WeChatLoginController {

    @Autowired
    MiniUserInfoService miniUserInfoService;

    @Autowired
    WechatService wechatService;

    @Autowired
    RedisUtils redisUtils;

    @ApiOperation(value = "获取手机验证码接口")
    @PostMapping("/getVerifyCode")
    public DResult getPhoneVerifyCode(@RequestBody Map<String, Object> map){
        String phone = map.get("phoneNumber").toString();
        String code = CommonUtils.getVerifyNumCode(4);
        log.info("获取手机验证码接口-> phone:{}, code:{}", phone, code);
        return DResult.of(code);
    }

    @ApiOperation(value = "获取SessionKey|OpenId")
    @PostMapping("/openId")
    public DResult getOpenId(@RequestBody Map<String, Object> map){
        if (Objects.isNull(map.get("code"))){
            return DResult.failed();
        }
        MiniUserVo userVo = new MiniUserVo();
        String jsCode = map.get("code").toString();
        log.info("获取SessionKey|OpenId-> jsCode:{}", jsCode);
        String jsonStr = wechatService.getWechatSessionAndOpenId(jsCode);
        if (StrUtil.isNotBlank(jsonStr)){
            JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
            String openId = jsonObject.getStr("openid");
            String sessionKey = jsonObject.getStr("session_key");
            map.put("openid", openId);
            map.put("sessionKey", sessionKey);
            // 验证用户是否存在
            MiniUserInfo userInfo = miniUserInfoService.queryMiniUserByOpenId(openId);
            if (Objects.isNull(userInfo)) {
                // 新增小程序用户
                userInfo = MiniUserInfo.builder()
                        .openId(openId)
                        .mLevelId(BasicConstants.ONE)
                        .build();
                miniUserInfoService.save(userInfo);
            }
            userVo = mergeMiniUserVo(userInfo, map);
        }
        return DResult.of(userVo);
    }

    @ApiOperation(value = "解密获取小程序用户信息")
    @PostMapping("/getMiniUser")
    public DResult getMiniUser(@RequestBody Map<String, Object> map){
        String iv = map.get("iv").toString();
        String encryptedData = map.get("encryptedData").toString();
        String sessionKey = map.get("sessionKey").toString();
        if (StrUtil.isBlank(iv) || StrUtil.isBlank(encryptedData) || StrUtil.isBlank(sessionKey)) {
            return DResult.failed(ResultCode.MINI_DECRYPT_PARAMS_LOSE.getCode(), ResultCode.MINI_DECRYPT_PARAMS_LOSE.getMsg());
        }
        // 解析
        MiniUserInfo userInfo = wechatService.mergeMiniUser(iv, encryptedData, sessionKey);
        // 验证用户是否存在
        if (Objects.nonNull(userInfo)) {
            // 更新小程序用户
            miniUserInfoService.updateMiniUser(userInfo);
        }
        return DResult.of(mergeMiniUserVo(userInfo, map));
    }

    @ApiOperation(value = "获取用户个人信息")
    @PostMapping("/getLoginUser")
    public DResult getLoginUser(@RequestBody Map<String, Object> map){
        String openId = map.get("openid").toString();
        if (StrUtil.isBlank(openId)) {
            return DResult.failed(ResultCode.MINI_OPENID_LOSE.getCode(), ResultCode.MINI_OPENID_LOSE.getMsg());
        }
        MiniUserInfo userInfo = miniUserInfoService.queryMiniUserByOpenId(openId);
        if (Objects.isNull(userInfo)) {
            return DResult.failed(ResultCode.MINI_USER_LOSE.getCode(), ResultCode.MINI_USER_LOSE.getMsg());
        }
        return DResult.of(mergeMiniUserVo(userInfo, map));
    }

    public MiniUserVo mergeMiniUserVo(MiniUserInfo userInfo, Map<String, Object> map){
        MiniUserVo userVo = new MiniUserVo();
        if (Objects.nonNull(userInfo)){
            userVo.setUser(userInfo);
        }
        if (map.containsKey("sessionKey")){
            userVo.setSessionKey(map.get("sessionKey").toString());
        }
        if (map.containsKey("code")){
            userVo.setCode(map.get("code").toString());
        }
        if (map.containsKey("openid")){
            String OpenId = map.get("openid").toString();
            // String token = getWechatToken(userInfo);
            userVo.setOpenid(OpenId);
            String userkey = RedisKey.USER_WECHAT.getValue() + OpenId;
            // userVo.setToken(token);
            // Token 存储用户信息
            long time = CommonUtils.USER_LOGIN_EXPIRE;
            if (redisUtils.hasKey(userkey)){
                long timeExpire = redisUtils.getExpire(userkey);
                if (timeExpire > 0) {
                    time = timeExpire;
                }
                redisUtils.set(userkey, JSONUtil.toJsonStr(userVo), time);

            }else{
                redisUtils.set(userkey, JSONUtil.toJsonStr(userVo), time);
            }
        }
        return userVo;
    }

}
